#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <dirent.h>
#include "unit_test.h"
#include "canfd_test.h"
#include "can_test.h"
#include "ai_test.h"
#include "di_test.h"
#include "pi_test.h"
#include "do_test.h"
#include "ao_test.h"
#include "pt100_test.h"

#define UNIT_TEST_NUM       (1 + 8)     /* 单元测试数量 */

static struct unit_test_t {
    uint8_t index;
    char name[32];
    char text[128];
    int (*unit_test)(int argc, char *argv[]);
} unit_test[UNIT_TEST_NUM];

static void init_unit_test(struct unit_test_t *unit_test) {
    unit_test[0] = (struct unit_test_t){0,  "null",     "0. 退出程序",      NULL};
    unit_test[1] = (struct unit_test_t){1,  "canfd",    "1. 测试 CANFD",    canfd_test};
    unit_test[2] = (struct unit_test_t){2,  "can",      "2. 测试 CAN",      can_test};
    unit_test[3] = (struct unit_test_t){3,  "ai",       "3. 测试 AI ",      ai_test};
    unit_test[4] = (struct unit_test_t){4,  "di",       "4. 测试 DI ",      di_test};
    unit_test[5] = (struct unit_test_t){5,  "pi",       "5. 测试 PI ",      pi_test};
    unit_test[6] = (struct unit_test_t){6,  "do",       "6. 测试 DO ",      do_test};
    unit_test[7] = (struct unit_test_t){7,  "ao",       "7. 测试 AO ",      ao_test};
    unit_test[8] = (struct unit_test_t){8,  "pt100",    "8. 测试 PT100 ",   pt100_test};
}

static void usage(void)
{
    uint8_t i = 0;

    printf("用法: ./unit_test [测试单元]\n");
    printf("测试单元:\n");
    for (i = 0; i < UNIT_TEST_NUM; i++) {
        printf("  %s\n", unit_test[i].name);
    }
}

/* 获取设备数量 */
uint8_t get_dev_num(const char *name)
{
    DIR *dir;
    struct dirent *entry;
    uint8_t count = 0;
    size_t name_len = strlen(name);

    /* 打开/dev目录 */
    dir = opendir("/dev");
    if (dir == NULL) {
        fprintf(stderr, "Open /dev failed\n");
        return 0;
    }
    /* 遍历 /dev 目录下的所有文件 */
    while ((entry = readdir(dir)) != NULL) {
        /* 检查文件名是否以指定名称开头 */
        if (strncmp(entry->d_name, name, name_len) == 0) {
            /* 精确匹配：设备名后面必须是数字或结束符 */
            char next_char = entry->d_name[name_len];
            
            /* 如果下一个字符是数字或者是字符串结束符，则匹配成功 */
            if (next_char == '\0' || (next_char >= '0' && next_char <= '9')) {
                count++;
            }
        }
    }
    closedir(dir);

    return count;
}

const char module_name[IET_TYPE_NUM][32] = {
    {"ECU"},
    {"DI"},
    {"DO"},
    {"AI"},
    {"AO"},
    {"PI"},
    {"SOE"},
    {"AC"},
    {"PT100"},
    {"IEPE"},
};

/* 获取模块类型 */
int get_module_type(uint8_t *type)
{
    uint8_t i = 0;
    int ret = 0;
    char input[32] = {0};

    printf("请选择模块类型:\n");
    for (i = 0; i < IET_TYPE_NUM; i++) {
        printf("%d.%s\n", i + 1, module_name[i]);
    }
    printf("请输入选择 (输入数字): ");
    if (fgets(input, sizeof(input), stdin) == NULL) {
        return -EFAULT;
    }
    ret = atoi(input);
    if (ret < 0 || ret > IET_TYPE_NUM) {
        return -EFAULT;
    } else {
        *type = ret;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    int ret = 0;
    uint8_t i = 0;

    init_unit_test(unit_test);
    while (1) {
        if (argc == 1) {
            usage();
            return EXIT_FAILURE;
        } else {
            for (i = 1; i < UNIT_TEST_NUM; i++) {
                if (strcmp(argv[1], unit_test[i].name) == 0) {
                    unit_test[i].unit_test(argc, argv);
                    return EXIT_SUCCESS;
                }
            }
            if (i == UNIT_TEST_NUM) {
                usage();
                return EXIT_FAILURE;
            }
        }
    }

    printf("%s return\n", __func__);

    return ret;
}
